// 这个trait用来实现打印标记`{:?}`
use std::fmt::Debug;
trait HasArea {
    fn area(&self) -> f64;
}
impl HasArea for Rectangle {
    fn area(&self) -> f64 {
        self.width * self.height
    }
}
#[derive(Debug)]
struct Rectangle {
    width: f64,
    height: f64,
}
#[allow(dead_code)]
struct Triangle {
    base: f64,
    height: f64,
}
// 泛型`T`必须实现`Debug`。只要满足这点，无论什么类型
// 都可以让下面函数正常工作
fn print_debug<T: Debug>(t: &T) {
    println!("{:?}", t);
}
// 泛型`T`必须实现`HasArea`.任意符合该约束的泛型的实例
// 都可以访问`HasArea`的`area`函数
fn area<T: HasArea>(t: &T) -> f64 {
    t.area()
}
fn main() {
    let rectangle = Rectangle {
        width: 10.0,
        height: 20.0,
    };
    let _triangle = Triangle {
        base: 10.0,
        height: 20.0,
    };
    print_debug(&rectangle);
    println!("{}", area(&rectangle));

    // print_debug(&_triangle)
    // println!("{}", area(&_triangle));
//     ^ 这里的`_triangle`没有实现`Debug`，所以编译不过
}
